module memory(
	//for cpu
	input clk,
	input we,
	input [7:0] addr,
	input [31:0] write_data,
	output [31:0] read_data,
	output hit,

	//for pdu
	input [7:0] pdu_addr,
	output [31:0] pdu_data
);
//组相联高速缓存
//8位地址，0为块偏移，2-1为组索引，7-3为标记位
//命中可以直接读取，不命中则需要等待一个周期才能送上来

wire write_memory_enable;
wire [63:0] read_from_memory_data,write_to_memory_data,write_to_cache_data,mem_data_for_pdu;
wire [6:0] read_from_memory_addr;

data_memory data_mem(
.a(read_from_memory_addr),
.d(write_to_memory_data),
.dpra(pdu_addr[7:1]),
.clk(clk),
.we(write_memory_enable),
.spo(read_from_memory_data),
.dpo(mem_data_for_pdu)
);

wire cache_hit,pdu_hit;
wire [31:0] read_for_pdu_cache,cache_half,read_data_from_cache;
wire [6:0] changed_addr;

assign hit=cache_hit;

assign read_from_memory_addr=cache_hit?changed_addr:addr[7:1];
assign write_to_cache_data=we?
	(cache_hit?
		(addr[0]?{write_data,cache_half}:{cache_half,write_data}):
		(addr[0]?{write_data,read_from_memory_data[31:0]}:{read_from_memory_data[63:32],write_data})
	):read_from_memory_data;

cache_groups cache(
	.clk(clk),
	.renew_data(write_to_cache_data),
	.addr(addr),
	.write_enable(~cache_hit|we),
	.hit(cache_hit),
	.read_from_group(read_data_from_cache),
	.another_half(cache_half),
	.if_changed(write_memory_enable),
	.changed_addr(changed_addr),
	.changed_data(write_to_memory_data),
	.pdu_addr(pdu_addr),
	.pdu_hit(pdu_hit),
	.read_for_pdu(read_for_pdu_cache)
);

assign pdu_data=pdu_hit?read_for_pdu_cache:
	(pdu_addr[0]?mem_data_for_pdu[63:32]:mem_data_for_pdu[31:0]);

assign read_data=(we&hit)?write_data:read_data_from_cache;
endmodule